package com.lfcsoft.server.message;

import com.lfcsoft.server.consts.RabbitConstants;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.ReturnedMessage;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.UUID;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * @author liqinwen
 * @date 2021-3-4 14:39
 */
@Slf4j
@Component
public class SendMessage implements RabbitTemplate.ConfirmCallback, RabbitTemplate.ReturnsCallback{
    @Autowired
    private RabbitTemplate rabbitTemplate;

    @PostConstruct
    public void init(){
        rabbitTemplate.setReturnsCallback(this);
        rabbitTemplate.setConfirmCallback(this);
        Runnable runnable=()->send("这是我发送的测试消息，测试id="+ UUID.randomUUID().toString());
        ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1);
        //定时发送消息给消息队列
        scheduledExecutorService.scheduleAtFixedRate(runnable,20,2, TimeUnit.SECONDS);
    }
    private void send(Object message) {
        CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());
        rabbitTemplate.convertAndSend(RabbitConstants.DEAD_EXCHANGE, RabbitConstants.DEAD_ROUTE_KEY, message, correlationData);
    }


    /**
     * confirm 确认消息投递成功
     * @param correlationData
     * @param ack
     * @param cause
     */
    @Override
    public void confirm(CorrelationData correlationData, boolean ack, String cause) {
        System.out.println("消息发送成功,发送ack确认,id="+correlationData.getId());
        if(ack){
            log.info("发送消息到exchange成功");
        }else{
            log.error("发送消息到exchange失败" + cause);
        }

    }

    /**
     *  ReturnCallback消息没有正确到达队列时触发回调，如果正确到达队列不执行
     *  config : 需要开启rabbitmq发送失败回退    publisher-returns    或rabbitTemplate.setMandatory(true);设置为true
     * @param returned
     */
    @Override
    public void returnedMessage(ReturnedMessage returned) {
        log.error("匹配queue失败:{}", returned.toString());
    }
}
